在這個最後要完善 User Login 的功能
完整的程式碼放在這邊可以做參考,如果真的改到一半不知道怎麼改的話
因為原本的教學大概有點年代,直接複製是沒辦法用的XD
https://github.com/whitefloor/Go-GraphQL
到這一篇就是全部程式碼都寫完了,不過還要找時間看一些進階資料
schema.resolvers.go
加強 CreateLink 錯誤處理以及新增回傳
func (r *mutationResolver) CreateLink(ctx context.Context, input model.NewLink) (*model.Link, error) {
user := auth.ForContext(ctx)
if user == nil {
return &model.Link{}, fmt.Errorf("access denied")
}
var link links.Link
link.User = user
linkID := link.Save()
link.Title = input.Title
link.Address = input.Address
graphqlUser := &model.User{
ID: user.ID,
Name: user.Username,
}
return &model.Link{ID: strconv.FormatInt(linkID, 10), Title: link.Title, Address: link.Address, User: graphqlUser}, nil
}
schema.resolvers.go
從 Database 取得 User 資料
func (r *queryResolver) Links(ctx context.Context) ([]*model.Link, error) {
var resultLinks []*model.Link
dbLinks := links.GetAll()
for _, link := range dbLinks {
graphqlUser := &model.User{
ID: link.User.ID,
Name: link.User.Username,
}
resultLinks = append(resultLinks, &model.Link{ID: link.ID, Title: link.Title, Address: link.Address, User: graphqlUser})
}
return resultLinks, nil
}
internal/links/links.go
Save method 改寫 Query
func (link Link) Save() int64 {
//#3
stmt, err := mig.Db.Prepare("INSERT INTO Links(Title,Address, UserID) VALUES(?,?, ?)")
if err != nil {
log.Fatal(err)
}
//#4
res, err := stmt.Exec(link.Title, link.Address, link.User.ID)
if err != nil {
log.Fatal(err)
}
//#5
id, err := res.LastInsertId()
if err != nil {
log.Fatal("Error:", err.Error())
}
log.Print("Row inserted!")
return id
}
internal/links/links.go
改寫 GetAll funciton
func GetAll() []Link {
stmt, err := mig.Db.Prepare("select L.id, L.title, L.address, L.UserID, U.Username from Links L inner join Users U on L.UserID = U.ID") // changed
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
rows, err := stmt.Query()
if err != nil {
log.Fatal(err)
}
defer rows.Close()
var links []Link
var username string
var id string
for rows.Next() {
var link Link
err := rows.Scan(&link.ID, &link.Title, &link.Address, &id, &username) // changed
if err != nil {
log.Fatal(err)
}
link.User = &users.User{
ID: id,
Username: username,
} // changed
links = append(links, link)
}
if err = rows.Err(); err != nil {
log.Fatal(err)
}
return links
}
到這邊我們全部的程式碼已經全部撰寫完成了$ go run server.go
打開 http://localhost:8080/
先使用以下 Query,會收到 access denied
mutation {
createLink(input: {title: "real link!", address: "www.graphql.org"}){
user{
name
}
}
}
接著使用 Login 或是 CreateUser 拿到新 Token 後
在網頁下方有可以新增 HTTP Header 的地方,新增 Token 後即可成功 CreateLink
{
"Authorization": "" // use your own generated token
}
https://www.howtographql.com/graphql-go/8-logged-in-user-object/
https://relay.dev/docs/guides/graphql-server-specification/
https://graphql.org/learn/